<script setup>
import { Search } from "@element-plus/icons-vue";
import { ref, onMounted, watch } from "vue";
const props = defineProps({
  roleId: {
    type: String,
    default: "",
  },
  modelValue: {
    type: Array,
    default: () => {
      return [];
    },
  },
});
const checkStrictly = ref(true);
const emits = defineEmits(["update:modelValue"]);
const customNodeClass = (data) => {
  if (data.isPenultimate) {
    return "is-penultimate";
  }
  return null;
};
const defaultProps = {
  children: "children",
  label: "name",
  class: customNodeClass,
};

const searchWord = ref("");
const isShowTree = ref(false);
const checkedKeys = ref([]);
const dataTree = ref([]);
const treeRef = ref(null);
watch(searchWord, (val) => {
  treeRef.value.filter(val);
});

const initCheck = (functionIdList) => {
  functionIdList.forEach((i) => {
    // 根据id 拿到 Tree 组件中的node的所有信息
    let node = treeRef.value.getNode(i);
    // node.isLeaf：判断当前节点是否为子节点
    if (node.isLeaf) {
      //如果是子节点，就把状态设置成选中
      if (node.parent.childNodes.every((item) => item.checked)) {
        node.parent.indeterminate = false;
      } else {
        node.parent.indeterminate = true;
        try {
          node.parent.parent.indeterminate = true;
        } catch (err) {
          console.log(err);
        }
      }
    }
  });
};

onMounted(async () => {
  const { data } = await getAssignableMenu(props.roleId);
  data.forEach((item) => {
    if (item.children.length > 0) {
      item.children.forEach((_item) => {
        _item.isPenultimate = true;
      });
    }
  });
  dataTree.value = data;
  const result = await getBindMenu(props.roleId);
  checkedKeys.value = result.data.map((item) => item.menuId);
  emits("update:modelValue", checkedKeys.value);

  isShowTree.value = true;
  setTimeout(() => {
    initCheck(checkedKeys.value);
  });
});

// 获取所有选中节点
const checkChange = () => {
  const keys = treeRef.value.getCheckedKeys();
  const parentKeys = treeRef.value.getHalfCheckedKeys();
  emits("update:modelValue", keys.concat(parentKeys));
};

const getFlatList = (treeData, child, arr) => {
  treeData.forEach((item) => {
    arr.push(item.id);
    if (item[child] && item[child].length > 0) {
      getFlatList(item[child], child, arr);
    }
  });
  return arr;
};

/**
 * 手动处理节点取消选中
 */
const hanleCheck = (data) => {
  let checkNode = treeRef.value.getNode(data);
  // 全选反选所有子节点
  const menuArr = getFlatList(checkNode.data.children, "children", []);
  menuArr.forEach((item) => {
    treeRef.value.setChecked(item, checkNode.checked);
  });
  // 如果子节点选中，所有父节点默认选中
  let firstParentId = "";
  const parentId = checkNode.parent.data.id;
  if (checkNode.level === 3) {
    firstParentId = checkNode.parent.parent.data.id;
  }
  if (checkNode.checked) {
    treeRef.value.setChecked(parentId, checkNode.checked);
    treeRef.value.setChecked(firstParentId, checkNode.checked);
  }
  // 二级菜单全部取消时，一级菜单也要取消
  if (checkNode.level === 2 && !checkNode.checked) {
    const menuId = checkNode.parent.data.children.map((item) => item.id);
    const keys = treeRef.value.getCheckedKeys();
    if (!keys.some((item) => menuId.includes(item))) {
      treeRef.value.setChecked(parentId, checkNode.checked);
    }
  }
  if (checkNode.parent.childNodes.every((item) => item.checked)) {
    checkNode.parent.indeterminate = false;
  } else {
    checkNode.parent.indeterminate = true;
    try {
      if (checkNode.level === 3) checkNode.parent.parent.indeterminate = true;
    } catch (err) {
      console.log(err);
    }
  }
};

/**
 * 搜索节点
 */
const filterNode = (value, data, node) => {
  if (!value) return true;
  let parentNode = node.parent,
    labels = [node.label],
    level = 1;
  while (level < node.level) {
    labels = [...labels, parentNode.label];
    parentNode = parentNode.parent;
    level++;
  }
  return labels.some((label) => label.indexOf(value) !== -1);
};
</script>
<template>
  <div class="pl30 h100p">
    <el-input
      style="width: 380px; margin-top: 10px"
      v-model="searchWord"
      placeholder="请输入权限名称"
      :prefix-icon="Search"
    />
    <div style="padding: 20px 0; color: #2b2b2b">功能权限</div>
    <div class="permission-container" style="height: calc(100% - 105px)">
      <el-scrollbar>
        <el-tree
          v-if="isShowTree"
          ref="treeRef"
          :data="dataTree"
          show-checkbox
          node-key="id"
          default-expand-all
          :default-checked-keys="checkedKeys"
          :expand-on-click-node="false"
          :props="defaultProps"
          @check="hanleCheck"
          :check-strictly="checkStrictly"
          @check-change="checkChange"
          :filter-node-method="filterNode"
        >
        </el-tree>
      </el-scrollbar>
    </div>
  </div>
</template>
<style lang="scss" scoped>
:deep(.el-tree-node.is-expanded.is-penultimate > .el-tree-node__children) {
  display: flex;
  flex-wrap: wrap;
}
:deep(.is-penultimate > .el-tree-node__children > div) {
  width: auto;
}
</style>
